﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using Timer=System.Threading.Timer;


namespace DZRemoteController
{
	public class GameController
	{
		private HtmlControlConfigSection controlSection = null;

		private static GameState state = new GameState();
		public static GameState State { get { return state; } }

		private WebBrowser webBrowser;
		private RuleManager rm;
		private IInputable inputDevice;
		private Timer timer;

		delegate void Delegate();


		public GameController(WebBrowser webBrowser)
		{
			rm = new RuleManager();
			controlSection = (HtmlControlConfigSection)ConfigurationManager.GetSection("htmlControlSection");
			this.webBrowser = webBrowser;
			this.webBrowser.Url = new Uri(ConfigurationManager.AppSettings["Url"]);
			this.webBrowser.DocumentCompleted += webBrowser_Completed;
			inputDevice = new ComPortInputer();
			inputDevice.CodeRecieved += new EventHandler<CodeRecievedEventArgs>(inputDevice_CodeRecieved);
			inputDevice.RefreshRecieved += new EventHandler(inputDevice_RefreshRecieved);
			inputDevice.Start();
			TimeSpan period = new TimeSpan(0, 0, Convert.ToInt32(ConfigurationManager.AppSettings["RefreshInterval"]));
			timer = new Timer(RefreshTimer, null, period, period);
		}

		public void RefreshTimer(object state)
		{
			State.IsMissionActive = false;
			State.IsCodesActive = false;
			webBrowser.Invoke(new Delegate(Refresh));
			
			
		}
		void webBrowser_Completed(object sender, WebBrowserDocumentCompletedEventArgs e)
		{
			ApplyRules();		
		}

		private void inputDevice_RefreshRecieved(object sender, EventArgs e)
		{
			State.IsCodesActive = true;
			State.IsMissionActive = false;

			webBrowser.Invoke(new Delegate(Refresh));
		}

		void inputDevice_CodeRecieved(object sender, CodeRecievedEventArgs e)
		{
			State.IsCodesActive = true;
			State.IsMissionActive = false;
			State.IsConnectionActive = true;
			webBrowser.Invoke(new Delegate(delegate { SendCode(e.Code); }));
		}

		public void Refresh()
		{
			webBrowser.Navigate(ConfigurationManager.AppSettings["Url"]);
		}

		public void SendCode(string code)
		{
			HtmlElement form = FindForm();
			HtmlElement textBox = FindTextBox(form);
			textBox.SetAttribute("value", code);
			form.InvokeMember("Submit");
		}

		private HtmlElement FindTextBox(HtmlElement form)
		{
			HtmlElement textbox = form.All[controlSection.TextBox.Name];
			if (textbox == null)
			{
				int n = controlSection.TextBox.OrderNo;
				HtmlElementCollection textboxes = form.GetElementsByTagName("INPUT");
				if (textboxes.Count > n)
					textbox = textboxes[n];
			}
			if (textbox == null)
				throw new ApplicationException(String.Format("Поле ввода '{0}' или Поле ввода с порядковым номером {1} не найдены", controlSection.TextBox.Name, controlSection.TextBox.OrderNo));
			return textbox;
		}

		private HtmlElement FindForm()
		{
			HtmlElement form = webBrowser.Document.All[controlSection.Form.Name];
			if (form == null)
			{
				int n = controlSection.Form.OrderNo;
				if(webBrowser.Document.Forms.Count > n)
					form = webBrowser.Document.Forms[n];	
			}
			if (form == null)
				throw new ApplicationException(String.Format("Имя формы {0} или форма с порядковым номером {1} не найдены", controlSection.Form.Name, controlSection.Form.OrderNo));
			return form;

			if (form != null)
				form.InvokeMember("Submit");
			else
				Refresh();
		}


		private string GetStringForSearch()
		{
			string s = webBrowser.Url.ToString();
			if( webBrowser.Document.Body  != null)
				s +=  webBrowser.Document.Body.InnerText;
			return s;
		}

		public void ApplyRules()
		{
			inputDevice.StartResponse();
			rm.ApplyRules(GetStringForSearch());
			inputDevice.EndResponse();
		}
	}
}
